package com.ctg.itrdc.sysmgr.permission.core.service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.util.CollectionUtils;

import com.ctg.itrdc.sysmgr.permission.core.IPermissionService;
import com.ctg.itrdc.sysmgr.permission.core.dao.IPermissionDao;
import com.ctg.itrdc.sysmgr.permission.core.dto.CommonRegionDTO;
import com.ctg.itrdc.sysmgr.permission.core.dto.FuncCompDTO;
import com.ctg.itrdc.sysmgr.permission.core.dto.FuncMenuDTO;
import com.ctg.itrdc.sysmgr.permission.core.dto.OrganizationDTO;
import com.ctg.itrdc.sysmgr.permission.core.dto.PoliticalLocationDTO;
import com.ctg.itrdc.sysmgr.permission.core.dto.StaffDTO;
import com.ctg.itrdc.sysmgr.permission.core.dto.SystemPostDTO;
import com.ctg.itrdc.sysmgr.permission.core.dto.SystemRolesDTO;
import com.ctg.itrdc.sysmgr.permission.core.dto.SystemUserDTO;

public class PermissionServiceImpl implements IPermissionService {
	private IPermissionDao permissionDao;

	private String sysCode;

	public void setSysCode(String sysCode) {
		this.sysCode = sysCode;
	}

	final static Comparator<Map<String, Object>> MENU_COMPARATOR = new Comparator<Map<String, Object>>() {

		@Override
		public int compare(Map<String, Object> o1, Map<String, Object> o2) {
			Number i1 = (Number) o1.get("menu_index");
			if (i1 == null) {
				return -1;
			}
			Number i2 = (Number) o2.get("menu_index");
			if (i2 == null) {
				return 1;
			}
			return i1.intValue() - i2.intValue();
		}
	};
	
	final static Comparator<FuncMenuDTO> MENUDTO_COMPARATOR = new Comparator<FuncMenuDTO>() {

		@Override
		public int compare(FuncMenuDTO o1, FuncMenuDTO o2) {
			Integer i1 = o1.getMenuIndex();
			if (i1 == null) {
				return -1;
			}
			Number i2 = (Number) o2.getMenuIndex();
			if (i2 == null) {
				return 1;
			}
			return i1.intValue() - i2.intValue();
		}
	};

	public IPermissionDao getPermissionDao() {
		return permissionDao;
	}

	public void setPermissionDao(IPermissionDao permissionDao) {
		this.permissionDao = permissionDao;
	}

	@Override
	public List<String> getRoleCodes(Long sysUserId, Long sysPostId) {
		return permissionDao.getRoleCodes(sysUserId, sysPostId);
	}

	@Override
	public List<String> getPermissions(Long sysUserId, Long sysPostId) {
		return permissionDao.getPermissions(sysUserId, sysPostId);
	}

	@Override
	public Map<String, Object> getUserByUsername(String userName) {
		return permissionDao.getUserByUsername(userName);
	}
	
	@Override
	public SystemUserDTO getUserBySysUserCode(String sysUserCode) {
		return permissionDao.getUserBySysUserCode(sysUserCode);
	}

	@Override
	public void updateLoginNum(Long sysUserId) {
		permissionDao.updateLoginNum(sysUserId);
	}

	@Override
	public boolean existRelation(Long sysUserId, Long sysPostId) {
		return permissionDao.existRelation(sysUserId, sysPostId);
	}

	@Override
	public List<Map<String, Object>> getPostByUId(Long sysUserId) {
		return permissionDao.getPostByUId(sysUserId);
	}
	
	@Override
	public List<SystemPostDTO> getPostByUserId(Long sysUserId) {
		return permissionDao.getPostByUserId(sysUserId);
	}
	
	@Override
	public List<Map<String, Object>> getRoleByUId(Long sysUserId) {
		return permissionDao.getRoleByUId(sysUserId);
	}
	
	@Override
	public List<SystemRolesDTO> getRoleByUserId(Long sysUserId) {
		return permissionDao.getRoleByUserId(sysUserId);
	}
	

	@Override
	public List<Map<String, Object>> selectMenuTree(Long sysUserId, Long sysPostId) {
		List<Map<String, Object>> menus = permissionDao.selectMenus(sysUserId, sysPostId, sysCode);
		if (menus == null || menus.size() == 0) {
			return null;
		}
		List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
		Map<Integer, Map<String, Object>> menuMaps = new HashMap<Integer, Map<String, Object>>();
		for (Map<String, Object> map : menus) {
			menuMaps.put((Integer) map.get("menu_id"), map);
			if (((Number) map.get("par_menu_id")).intValue() == 0) {
				result.add(map);
			}
		}
		for (Map<String, Object> map : menus) {
			Number parMenuId = (Number) map.get("par_menu_id");
			Map<String, Object> menu = menuMaps.get(new Integer(parMenuId.intValue()));
			if (menu != null) {
				addItem(menu, map);
			}
		}
		sortMenuTree(result);
		return result;
	}

	@Override
	public List<FuncMenuDTO> getMenuTree(Long sysUserId, Long sysPostId) {
		List<FuncMenuDTO> menus = permissionDao.selectMenuList(sysUserId, sysPostId, sysCode);
		if (menus == null || menus.size() == 0) {
			return null;
		}
		List<FuncMenuDTO> result = new ArrayList<FuncMenuDTO>();
		Map<Long, FuncMenuDTO> menuMaps = new HashMap<Long, FuncMenuDTO>();
		for (FuncMenuDTO menu : menus) {
			menuMaps.put(menu.getMenuId(), menu);
			if (menu.getParMenuId() == 0) {
				result.add(menu);
			}
		}
		for (FuncMenuDTO menu : menus) {
			Long parMenuId = menu.getParMenuId();
			FuncMenuDTO parMenu = menuMaps.get(parMenuId);
			if (parMenu != null) {
				addItem(parMenu, menu);
			}
		}
		sortMenuList(result);
		return result;
	}
	
	@SuppressWarnings("unchecked")
	private void sortMenuTree(List<Map<String, Object>> result) {
		Collections.sort(result, MENU_COMPARATOR);
		for (Map<String, Object> map : result) {
			List<Map<String, Object>> item = (List<Map<String, Object>>) map.get("item");
			if (item != null) {
				sortMenuTree(item);
			}
		}
	}
	
	private void sortMenuList(List<FuncMenuDTO> result) {
		Collections.sort(result, MENUDTO_COMPARATOR);
		for (FuncMenuDTO menu : result) {
			List<FuncMenuDTO> item = menu.getItem();
			if (item != null) {
				sortMenuList(item);
			}
		}
	}
	
	

	@SuppressWarnings("unchecked")
	private void addItem(Map<String, Object> menu, Map<String, Object> map) {
		List<Map<String, Object>> item = (List<Map<String, Object>>) menu.get("item");
		if (item == null) {
			item = new ArrayList<Map<String, Object>>();
			menu.put("has_children", Boolean.TRUE);
			menu.put("item", item);
		}
		item.add(map);
	}
	
	private void addItem(FuncMenuDTO parMenu, FuncMenuDTO menu) {
		List<FuncMenuDTO> item = parMenu.getItem();
		if (item == null) {
			item = new ArrayList<FuncMenuDTO>();
			parMenu.setHasChildren(true);
			parMenu.setItem(item);
		}
		item.add(menu);
	}

	@Override
	public List<Map<String, Object>> selectCompList(Long sysUserId, Long sysPostId) {
		return permissionDao.selectCompList(sysUserId, sysPostId, sysCode);
	}
	
	@Override
	public List<FuncCompDTO> getCompList(Long sysUserId, Long sysPostId) {
		return permissionDao.getCompList(sysUserId, sysPostId, sysCode);
	}

	@Override
	public Map<String, Object> getOrgById(Long orgId) {
		return permissionDao.getOrgById(orgId);
	}
	
	@Override
	public OrganizationDTO getOrgByOrgId(Long orgId) {
		return permissionDao.getOrganizationById(orgId);
	}

	@Override
	public Map<String, Object> getStaffById(Long staffId) {
		return permissionDao.getStaffById(staffId);
	}
	
	@Override
	public StaffDTO getStaffByStaffId(Long staffId) {
		return permissionDao.getStaffByStaffId(staffId);
	}

	@Override
	public Map<String, Object> getPostById(Long sysPostId) {
		return permissionDao.getPostById(sysPostId);
	}
	
	@Override
	public SystemPostDTO getPostByPostId(Long sysPostId) {
		return permissionDao.getPostByPostId(sysPostId);
	}

	@Override
	public Map<String, Object> getUserById(Long sysUserId) {
		return permissionDao.getUserById(sysUserId);
	}
	
	@Override
	public SystemUserDTO getUserByUserId(Long sysUserId) {
		return permissionDao.getUserByUserId(sysUserId);
	}

	@Override
	public void updatePassword(Long sysUserId, String password) {
		permissionDao.updatePassword(sysUserId, password);
	}
	
	@Override
	public Map<String, Object> getParRegionByType(Long commonRegionId, String regionType) {
		List<Map<String, Object>> res = permissionDao.getParentRegion(commonRegionId);
		if(res.size() == 0 || regionType == null) {
			return null;
		} else {
			Map<String, Object> data = res.get(0);
			String parType = (String)data.get("REGION_TYPE");
			if(regionType.equals(parType)) {
				return data;
			} else {
				Long parId = (Long)data.get("COMMON_REGION_ID");
				return getParRegionByType(parId, regionType);
			}
		}
	}
	
	@Override
	public CommonRegionDTO getParentRegionByType(Long commonRegionId, String regionType) {
		CommonRegionDTO dto = permissionDao.getParentRegionById(commonRegionId);
		if(dto == null || regionType == null) {
			return null;
		} else {
			if(regionType.equals(dto.getRegionType())) {
				return dto;
			} else {
				Long parId = dto.getCommonRegionId();
				return getParentRegionByType(parId, regionType);
			}
		}
	}
	
	@Override
	public Map<String, Object> getStaffNameById(Long staffId) {
		List<Map<String, Object>> list = permissionDao.getStaffNameById(staffId);
		if(list.size() == 0) {
			return null;
		}
		return list.get(0);
	}
	
	@Override
	public String getStaffNameByStaffId(Long staffId) {
		return permissionDao.getStaffNameByStaffId(staffId);
	}
	
	@Override
	public Map<String, Object> getRzOrgIdByStaffId(Long staffId) {
		List<Map<String, Object>> list = permissionDao.getRzOrgIdByStaffId(staffId);
		if(list.size() == 0) {
			return null;
		}
		return list.get(0);
	}
	
	@Override
	public Long getRzOrgIdBystaffid(Long staffId) {
		return permissionDao.getRzOrgIdBystaffId(staffId);
	}
	
	@Override
	public Map<String, Object> getRzOrgCodeById(Long rzOrgId) {
		List<Map<String, Object>> list = permissionDao.getRzOrgCodeById(rzOrgId);
		if(list.size() == 0) {
			return null;
		}
		return list.get(0);
	}
	
	@Override
	public String getRzOrgCodeByOrgId(Long orgId) {
		return permissionDao.getRzOrgCodeByOrgId(orgId);
	}
	
	@Override
	public Map<String, Object> getOrgByUserIdAndPostId(Long userId, Long postId) {
		List<Map<String, Object>> list = permissionDao.getOrgByUserIdAndPostId(userId, postId);
		if(list.size() == 0) {
			return null;
		}
		return list.get(0);
	}
	
	@Override
	public OrganizationDTO getOrgByUserAndPostId(Long userId, Long postId) {
		List<OrganizationDTO> list = permissionDao.getOrganizationByUserIdAndPostId(userId, postId);
		if(CollectionUtils.isEmpty(list)) {
			return null;
		}
		return list.get(0);
	}
	
	@Override
	public Map<String, Object> getRegionNameById(Long comRegionId) {
		List<Map<String, Object>> list = permissionDao.getRegionNameById(comRegionId);
		if(list.size() == 0) {
			return null;
		}
		return list.get(0);
	}
	
	@Override
	public String getRegionNameByRegionId(Long comRegionId) {
		return permissionDao.getRegionNameByRegionId(comRegionId);
	}
	
	@Override
	public List<Map<String, Object>> getPoliticalLocation(Long regionId, String locType) {
		return permissionDao.getPoliticalLocation(regionId, locType);
	}
	
	@Override
	public PoliticalLocationDTO getPoliticalLocationByRegionId(Long regionId) {
		return permissionDao.getPoliticalLocationByRegionId(regionId);
	}
}
